package com.osce.score.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csce.domain.entity.score.*;
import com.csce.domain.entity.score.dto.ScoreScoreDto;
import com.csce.domain.entity.score.vo.ScoreScoreVo;
import com.doudou.core.container.ArrUtil;
import com.doudou.core.container.ListUtil;
import com.doudou.core.container.SetUtil;
import com.doudou.core.lang.ObjUtil;
import com.doudou.core.throwable.GlobalException;
import com.osce.interfaces.score.IScoreExExamPlaceAllotService;
import com.osce.interfaces.score.IScoreExExamScoreService;
import com.osce.interfaces.score.IScoreExExamSessionService;
import com.osce.interfaces.score.IScoreSheetService;
import com.osce.score.mapper.ScoreExExamMarkMapper;
import com.osce.score.mapper.ScoreExExamSessionMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 考试场次Service业务层处理
 *
 * @author zzx
 * @since 2023-09-07
 */
@Service
public class ScoreExExamSessionServiceImpl extends ServiceImpl<ScoreExExamSessionMapper, ScoreExExamSession> implements IScoreExExamSessionService {

    @Resource private IScoreExExamPlaceAllotService allotService;
    @Resource private ScoreExExamMarkMapper markMapper;
    @Resource private IScoreExExamScoreService scoreService;
    @Resource private IScoreSheetService sheetService;


    /**
     * 查询考试场次
     *
     * @param id 考试场次主键
     * @return 考试场次
     */
    @Override
    public ScoreExExamSession selectScoreExExamSessionById(Long id) {
        return baseMapper.selectScoreExExamSessionById(id);
    }

    /**
     * 查询考试场次列表
     *
     * @param scoreExExamSession 考试场次
     * @return 考试场次
     */
    @Override
    public List<ScoreExExamSession> selectScoreExExamSessionList(ScoreExExamSession scoreExExamSession) {
        return baseMapper.selectScoreExExamSessionList(scoreExExamSession);
    }

    /**
     * 新增考试场次
     *
     * @param scoreExExamSession 考试场次
     * @return 结果
     */
    @Transactional
    @Override
    public int insertScoreExExamSession(ScoreExExamSession scoreExExamSession) {
        int rows = baseMapper.insertScoreExExamSession(scoreExExamSession);
        allotService.insertScoreExExamPlaceAllot(scoreExExamSession.getScoreExExamPlaceAllotList(), scoreExExamSession.getId());
        return rows;
    }

    /**
     * 修改考试场次
     *
     * @param scoreExExamSession 考试场次
     * @return 结果
     */
    @Transactional
    @Override
    public int updateScoreExExamSession(ScoreExExamSession scoreExExamSession) {
        //check
        this.checkRepeatExaminer(scoreExExamSession);
        // db
        if (ListUtil.isNotEmpty(scoreExExamSession.getScoreExExamPlaceAllotList())) {
            allotService.deleteScoreExExamPlaceAllotBySessionId(scoreExExamSession.getId());
            allotService.insertScoreExExamPlaceAllot(scoreExExamSession.getScoreExExamPlaceAllotList(), scoreExExamSession.getId());
        }
        return baseMapper.updateScoreExExamSession(scoreExExamSession);
    }

    /**
     * check 更新brfore
     */
    private void checkRepeatExaminer(ScoreExExamSession scoreExExamSession) {
        //考官重复校验
        List<Long> list = scoreExExamSession.examinerList();
        if (ListUtil.isNotEmpty(list)){
            List<Long> isNullList = list.stream().filter(ObjUtil::isNotNull).collect(Collectors.toList());
            Set<Long> distinctList = SetUtil.hashSet(isNullList);
            if (distinctList.size() != isNullList.size()) {
                throw new GlobalException("考官不可重复赋予角色");
            }
        }
    }

    @Override
    public int clearExaminer(Long id) {
        return baseMapper.clearExaminer(id);
    }


    /**
     * 批量删除考试场次
     *
     * @param ids 需要删除的考试场次主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteScoreExExamSessionByIds(Long[] ids) {
        allotService.deleteScoreExExamPlaceAllotBySessionIds(ids);
        return baseMapper.deleteScoreExExamSessionByIds(ids);
    }

    /**
     * 删除考试场次信息
     *
     * @param id 考试场次主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteScoreExExamSessionById(Long id) {
        allotService.deleteScoreExExamPlaceAllotBySessionId(id);
        return baseMapper.deleteScoreExExamSessionById(id);
    }

    @Override
    @Transactional
    public int deleteScoreExExamSessionByExamId(Long examId) {
        //查询该考试下的所有节次
        List<Long> ids = baseMapper.selectScoreExExamSessionIdsByExamId(examId);
        if (ListUtil.isEmpty(ids)){
            return 0;
        }
        return deleteScoreExExamSessionByIds(ArrUtil.toArray(ids,Long.class));
    }

    @Override
    @Transactional
    public int deleteScoreExExamSessionByExamIds(Long[] examIds) {
        //查询该考试下的所有节次
        List<Long> ids = baseMapper.selectScoreExExamSessionIdsByExamIds(examIds);
        return deleteScoreExExamSessionByIds(ids.toArray(new Long[0]));
    }

    /**
     * 根据考试编号查询节次列表
     *
     * @param examId 考试编号
     */
    @Override
    public List<ScoreExExamSession> selectScoreExExamSessionsByExamId(Long examId) {
        return baseMapper.selectScoreExExamSessionsByExamId(examId);
    }

    @Override
    @Transactional
    public int batchExExamSession(List<ScoreExExamSession> sessions) {
        int i = baseMapper.batchExExamSession(sessions);
        if (i > 0) {
            if (sessions.size() < 10) {
                allotService.insertScoreExExamPlaceAllotBySession(sessions);
            } else {//如超过了10条，则分批插入
                for (List<ScoreExExamSession> examSessions : ListUtil.split(sessions, sessions.size() / 2)) {
                    allotService.insertScoreExExamPlaceAllotBySession(examSessions);
                }
            }
        }
        return i;
    }

    /**
     * 获取考试成绩列表
     */
    @Override
    public List<ScoreScoreVo> getExamScoreList(ScoreScoreDto scoreScoreDto) {
        return baseMapper.getExamScoreList(scoreScoreDto);
    }


    @Override
    public ScoreSheet selectAllotSheetParse(Long markId) {
        ScoreExExamMark scoreExExamMark = markMapper.selectScoreExExamMarkById(markId);
        Map<Long, ScoreExExamScore> scores = scoreService.selectScoreMapByMarkId(markId);
        //查询评分表
        ScoreSheet sheet = sheetService.selectScoreSheetById(scoreExExamMark.getSheetId());
        //整合分数
        for (ScoreSheetStep step : sheet.getSteps()) {
            step.setMark(scores.get(step.getId()).getScore());
        }
        return sheet;
    }

}
